<?php

declare (strict_types = 1);

namespace app\admin;

use think\App;
use think\exception\ValidateException;
use think\response\Json;
use think\Validate;
use think\facade\Request;

use app\admin\model\AdminMenu;
use app\admin\model\AdminRoleMenu;

/**
 * 控制器基础类
 */
abstract class BaseController {

    /**
     * Request实例
     * @var \think\Request
     */
    protected $request;

    /**
     * 应用实例
     * @var \think\App
     */
    protected $app;

    /**
     * 是否批量验证
     * @var bool
     */
    protected $batchValidate = false;

    /**
     * 控制器中间件
     * @var array
     */
    protected $middleware = [];

    /**
     * 构造方法
     * @access public
     * @param  App  $app  应用对象
     */
    public function __construct(App $app) {
        $this->app = $app;
        $this->request = $this->app->request;

        // 控制器初始化
        $this->initialize();
    }

    // 初始化
    protected function initialize() {
        $request = Request::instance();

        $url = $request->url(true);
        $module = $request->root(); //模块名
        $module = substr($module,1);
        $controller = $request->controller(); //控制器名
        $action = $request->action(); //方法名
        $token = Request::instance()->header('token');
        $requestType = Request::instance()->header('requestType');//1app调用后台的接口不需要验证
        if (!self::isMobile()){
            //if($requestType != 1){
            if (empty($token)) {
                $token = input('param.token');
            }

            $res = checkToken($token);
            $object =  json_decode(json_encode($res),true);
            $no_auth_action = ['Public','Login']; //不需要验证的方法
            if($object['code']!=1){
                echo json_encode(['code' => 4,'msg' => $object['msg'],'data' => '']);die;
            }else{
                $role_id = $object['data']['role_id'];
                $adminRoleID = AdminRoleMenu::where('role_id',$role_id)->column('menu_id');

                /*
                 * 有用 崔彦雷注
                 */
                if (!(in_array($controller, $no_auth_action) || in_array($action,$no_auth_action))) {
                    $MenuID = AdminMenu::where('module', '=', $module)
                        ->where('controller', '=', $controller)
                        ->where('action', '=', $action)
                        ->where('status',1)
                        ->value('id');
                    if (!in_array($MenuID,$adminRoleID)) {
                        echo json_encode(['code' => 5,'msg' => '您没权限操作','data' => '']);die;
                    }
                }
            }

        }
    }

    /*
     *判断是否为手机端使用；
     */
    function isMobile(){
        // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
        if (isset ($_SERVER['HTTP_X_WAP_PROFILE'])){
            return TRUE;
        }
        // 如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
        if (isset ($_SERVER['HTTP_VIA'])){
            return stristr($_SERVER['HTTP_VIA'], "wap") ? TRUE : FALSE;// 找不到为flase,否则为TRUE
        }
        // 判断手机发送的客户端标志,兼容性有待提高
        if (isset ($_SERVER['HTTP_USER_AGENT'])) {
            $clientkeywords = array (
                'mobile',
                'nokia',
                'sony',
                'ericsson',
                'mot',
                'samsung',
                'htc',
                'sgh',
                'lg',
                'sharp',
                'sie-',
                'philips',
                'panasonic',
                'alcatel',
                'lenovo',
                'iphone',
                'ipod',
                'blackberry',
                'meizu',
                'android',
                'netfront',
                'symbian',
                'ucweb',
                'windowsce',
                'palm',
                'operamini',
                'operamobi',
                'openwave',
                'nexusone',
                'cldc',
                'midp',
                'wap'
            );
            // 从HTTP_USER_AGENT中查找手机浏览器的关键字
            if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))){
                return TRUE;
            }
        }
        if (isset ($_SERVER['HTTP_ACCEPT'])){ // 协议法，因为有可能不准确，放到最后判断
            // 如果只支持wml并且不支持html那一定是移动设备
            // 如果支持wml和html但是wml在html之前则是移动设备
            if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== FALSE) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === FALSE || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))){
                return TRUE;
            }
        }
        return FALSE;
    }

    /**
     * 判断是否为合法的身份证号码
     * @param $mobile
     * @return int
     */
    function isCreditNo($vStr)
    {
        $vCity = array(
            '11', '12', '13', '14', '15', '21', '22',
            '23', '31', '32', '33', '34', '35', '36',
            '37', '41', '42', '43', '44', '45', '46',
            '50', '51', '52', '53', '54', '61', '62',
            '63', '64', '65', '71', '81', '82', '91'
        );
        if (!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $vStr)) return false;
        if (!in_array(substr($vStr, 0, 2), $vCity)) return false;
        $vStr = preg_replace('/[xX]$/i', 'a', $vStr);
        $vLength = strlen($vStr);
        if ($vLength == 18) {
            $vBirthday = substr($vStr, 6, 4) . '-' . substr($vStr, 10, 2) . '-' . substr($vStr, 12, 2);
        } else {
            return false;//新增
            //$vBirthday = '19' . substr($vStr, 6, 2) . '-' . substr($vStr, 8, 2) . '-' . substr($vStr, 10, 2);//原来的代码；
        }
        if (date('Y-m-d', strtotime($vBirthday)) != $vBirthday) return false;
        if ($vLength == 18) {
            $vSum = 0;
            for ($i = 17; $i >= 0; $i--) {
                $vSubStr = substr($vStr, 17 - $i, 1);
                $vSum += (pow(2, $i) % 11) * (($vSubStr == 'a') ? 10 : intval($vSubStr, 11));
            }
            if ($vSum % 11 != 1) return false;
        }
        return true;
    }

    /**
     * 验证数据
     * @access protected
     * @param  array        $data     数据
     * @param  string|array $validate 验证器名或者验证规则数组
     * @param  array        $message  提示信息
     * @param  bool         $batch    是否批量验证
     * @return array|string|true
     * @throws ValidateException
     */
    protected function validate(array $data, $validate, array $message = [], bool $batch = false) {
        if (is_array($validate)) {
            $v = new Validate();
            $v->rule($validate);
        } else {
            if (strpos($validate, '.')) {
                // 支持场景
                [$validate, $scene] = explode('.', $validate);
            }
            $class = false !== strpos($validate, '\\') ? $validate : $this->app->parseClass('validate', $validate);
            $v = new $class();
            if (!empty($scene)) {
                $v->scene($scene);
            }
        }

        $v->message($message);

        // 是否批量验证
        if ($batch || $this->batchValidate) {
            $v->batch(true);
        }
        return $v->failException(true)->check($data);
    }

    /*
     * 返回json
     */

    public function ajaxReturn($code, $msg, $data='default') {
        $array = [
            'code' => $code,
            'msg' => $msg,
            'data' => $data,
        ];
        header('Access-Control-Allow-Origin: *');
        header('Access-Control-Expose-Headers: token');
        header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, token,requestType");
        header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
        header('Content-Type:application/json; charset=utf-8');
//        return json_encode($array);
        return json($array);
    }

    /**
     * @成功返回的数据
     * @param $msg
     * @param null $data
     * @param int $count
     * @return Json
     */
    function suc_json($msg, $data = 1, $count = 0) {
        return json(['code' => 100, 'data' => $data, 'count' => $count, 'msg' => $msg]);
    }

    /**
     * @失败返回的数据
     * @param $msg
     * @param string $data
     * @return Json
     */
    function err_json($msg, $data = '') {
        return json(['code' => 99, 'data' => $data, 'count' => 0, 'msg' => $msg]);
    }

}
